﻿#pragma once

#include "OCMain/Environment.h"
#include "OCMain/Log.h"
#include "OCMain/Timer.h"
#include "OCMain/FileUtil.h"
#include "OCMain/Date.h"
#include "OCServer/ServerUtil.h"
#include "OCGrib/GribReader.h"
#include "OCVolume/VolumeEncoder.h"
#include "OCVolume/Swan3.h"
#include "OCVolume/Swan.h"
#include "OCGIS/TiffWriter.h"
#include "OCNetCDF/NetCDFReader.h"
#include "OCVolume/VolumeMesh.h"

using namespace OCPP;
using namespace OCPP::Volume;


void TestNetcdf1()
{
	String outPath = "e:\\test\\CAP3D";
	String dataPath = "E:\\volume\\垂直观测\\rada\\";
	//Swan3 reader;
	//reader.splitLOD(
	//	U2A(joinPath(dataPath, "Z_RADA_C_BABJ_20240720000016_P_DOR_ACHN_CREF_20240719_235400.bin")),
	//	outPath);
	Uint8Vector crefData;
	for (int i = 0; i < 24; i++) {
		StringStream sstream;
		sstream << std::setw(2) << std::setfill('0') << i;
		String outPath2 = joinPath(outPath, sstream.str());
		FileUtil::makeDirectory(outPath2);
		String name = str_format("Z_RADA_C_BABJ_20240720000119_P_DOR_ACHN_CAP_20240719_235400_%s.bin", sstream.str().c_str());
		Swan3 reader;
		reader.splitLOD(
			U2A(joinPath(dataPath, name)),
			outPath2, crefData);
	}

	std::ofstream ofs(joinPath(outPath, "cref.bin"), std::ios::binary);
	ofs.write((char*)&crefData[0], crefData.size() * sizeof(uint8));
}

void TestNetcdf()
{
	String dataPath = "E:\\volume";
	String cachePath = "E:\\test";

	FileUtil::formatPathNoSeperator(dataPath);
	FileUtil::formatPathNoSeperator(cachePath);

	StringMap globalOptions;
	globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
	globalOptions[VolumeOptions::Config::NameGZipCompress] = "yes";
	globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
	globalOptions[VolumeOptions::Config::NameMakeDirForFile] = "yes";


#if 0
	{
		//globalOptions[VolumeOptions::Config::NameClipRange] = "45 -45 135 45";
		VolumeComputeList computeList;
		String gibName1 = U2A("北京华信\\法比安台风个例\\GRAPESGFSG_WIU_103_2023051700_GLB_1_2.grib2");
		String gibName2 = U2A("北京华信\\法比安台风个例\\GRAPESGFSG_WIV_103_2023051700_GLB_1_2.grib2");
		computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_height_above_ground" });
		computeList.push_back({ joinPath(dataPath, gibName2) ,"v-component_of_wind_height_above_ground" });
		GribReader::extract(computeList, std::make_shared<NcAlgorithmUV>(), globalOptions, 0);
	}
#endif 

#if 0
	{
		globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeWind);
		globalOptions[VolumeOptions::Config::NameClipRange] = "70 -14.5 79 -3.5";

		VolumeComputeList computeList;
		String gibName1 = U2A("北京华信\\法比安台风个例\\GRAPESGFSG_WIU_100_2023051700_GLB_1_2.grib2");
		String gibName2 = U2A("北京华信\\法比安台风个例\\GRAPESGFSG_WIV_100_2023051700_GLB_1_2.grib2");
		computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_isobaric" });
		computeList.push_back({ joinPath(dataPath, gibName2) ,"v-component_of_wind_isobaric" });
		//GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), globalOptions, -1, 0);
		GribReader::extract(computeList, std::make_shared<NcAlgorithmNone>(), globalOptions, -30000, -1);
	}
#endif 
#if 0
	{
		//globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeWind);
		//globalOptions[VolumeOptions::Config::NameClipRange] = "71 -16 79 -3";

		VolumeComputeList computeList;
		String gibName1 = U2A("数据网\\Z_NAFP_C_BABJ_20231122153707_P_HRCLDAS_RT_CHN_0P01_HOR-UWIN-2023112215.GRB2");
		String gibName2 = U2A("数据网\\Z_NAFP_C_BABJ_20231122153710_P_HRCLDAS_RT_CHN_0P01_HOR-VWIN-2023112215.GRB2");
		computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_height_above_ground" });
		computeList.push_back({ joinPath(dataPath, gibName2) ,"v-component_of_wind_height_above_ground" });
		GribReader::extract(computeList, std::make_shared<NcAlgorithmUV>(), globalOptions);
	}
#endif 
#if 0
	// 数据网1KM大数据切片
	{
		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueJsonWriter;
		globalOptions[VolumeOptions::Config::NameReverseY] = "true";
		VolumeComputeList computeList;
		String gibName1 = U2A("数据网\\Z_NAFP_C_BABJ_20231120200455_P_HRCLDAS_RT_CHN_0P01_HOR-TAIR-2023112020.GRB2");
		GribReader reader;
		reader.open(joinPath(dataPath, gibName1), true);
		VolumeOptions options(globalOptions, new TiffWriter);
		options.getWriter().setOutputPath(cachePath);
		options.getWriter().setMakeDirForFile(true);

		reader.extract("Temperature_height_above_ground", options, 0);
	}
#endif 

#if 0
	// 梅花
	//{
	//	globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeWind);
	//	globalOptions[VolumeOptions::Config::NameClipRange] = "120 24 130 33";

	//	VolumeComputeList computeList;
	//	String gibName1 = U2A("北京NMIC\\Z_NAFP_C_BABJ_20220914003017_P_CRA_RAP_CHN_0P05_HOR_MUL_2022091400.grib2");
	//	computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_isobaric" });
	//	computeList.push_back({ joinPath(dataPath, gibName1) ,"v-component_of_wind_isobaric" });
	//	//computeList.push_back({ joinPath(dataPath, gibName1) ,"Vertical_velocity_pressure_isobaric" });
	//	//GribReader::extract(computeList, std::make_shared<NcAlgorithmNone>(), globalOptions, -1, -1);
	//	GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), globalOptions, -30000, -1);
	//}

	{
		globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString({ -40.0f,40.0f });
		globalOptions[VolumeOptions::Config::NameClipRange] = "120 24 130 33";
		globalOptions[VolumeOptions::Config::NameFixValue] = "-273.15";

		VolumeComputeList computeList;
		String gibName1 = U2A("北京NMIC\\Z_NAFP_C_BABJ_20220914003017_P_CRA_RAP_CHN_0P05_HOR_MUL_2022091400.grib2");
		GribReader reader;
		reader.open(joinPath(dataPath, gibName1), true);
		reader.extract("Temperature_isobaric", globalOptions, -30000, -1);

	}
#endif 

#if 0
	{
		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueJsonWriter;

		VolumeComputeList computeList;
		String gibName1 = U2A("data2024\\gfs.t12z.pgrb2.0p25.f000");
		GribReader reader;
		reader.open(joinPath(dataPath, gibName1), true);
		//reader.extract("Temperature_height_above_ground", globalOptions, -1, -1);
		//reader.extract("Total_cloud_cover_entire_atmosphere", globalOptions, -1, -1);
		//reader.extract("Relative_humidity_height_above_ground", globalOptions, -1, -1);

		//computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_height_above_ground" });
		//computeList.push_back({ joinPath(dataPath, gibName1) ,"v-component_of_wind_height_above_ground" });
		//GribReader::extract(computeList, std::make_shared<NcAlgorithmNone>(), globalOptions, 0);


		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
		globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeWind);
		computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_isobaric" });
		computeList.push_back({ joinPath(dataPath, gibName1) ,"v-component_of_wind_isobaric" });
		GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), globalOptions
			, -30000, -1);
	}
#endif 


#if 0
	{
		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueJsonWriter;

		VolumeComputeList computeList;
		String gibName1 = U2A("垂直观测\\ART_ATM_GLB_0P10_6HOR_ANAL_2024020100.grib2");
		GribReader reader;
		reader.open(joinPath(dataPath, gibName1), true);
		//reader.extract("Temperature_height_above_ground", globalOptions, -1, -1);
		//reader.extract("Total_cloud_cover_entire_atmosphere", globalOptions, -1, -1);
		//reader.extract("Relative_humidity_height_above_ground", globalOptions, -1, -1);

		//computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_height_above_ground" });
		//computeList.push_back({ joinPath(dataPath, gibName1) ,"v-component_of_wind_height_above_ground" });
		//GribReader::extract(computeList, std::make_shared<NcAlgorithmNone>(), globalOptions, 0);

		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
		globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeSH);
		globalOptions[VolumeOptions::Config::NameClipRange] = "70 0 140 60";
		reader.extract("Specific_humidity_isobaric", globalOptions, -1, -1);

		//computeList.push_back({ joinPath(dataPath, gibName1) ,"u-component_of_wind_isobaric" });
		//computeList.push_back({ joinPath(dataPath, gibName1) ,"v-component_of_wind_isobaric" });
		//GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), globalOptions
		//	, -1, -1);
	}
#endif 


#if 0
	{
		String gribPath = joinPath(dataPath, U2A("海南\\ART"));
		auto files = FileUtil::findFiles(gribPath);
		for (const auto& f : files)
		{
			if (f == "." || f == "..") continue;
			String gibName1 = joinPath(gribPath, f);
			VolumeComputeList computeList;
			String cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\Hainan");
			globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
			GribReader reader;
			reader.open(gibName1, true);
			globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
			globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangeWind);
			globalOptions[VolumeOptions::Config::NameClipRange] = "103.0 12.0 119.0 25.0";

			// 格美
			//globalOptions[VolumeOptions::Config::NameClipRange] = "120.0 12.0 130.0 25.0";

			// 温度
			//globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString({-40.0f,40.0f});
			//globalOptions[VolumeOptions::Config::NameFixValue] = "-273.15";
			//reader.extract("Temperature_isobaric", globalOptions, -30000, -1);

			//globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString({ 1000.0f,10000.0f });
			//reader.extract("Geopotential_height_isobaric", globalOptions, -30000, -1);

			// 风速
			computeList.push_back({ gibName1 ,"u-component_of_wind_isobaric" });
			computeList.push_back({ gibName1 ,"v-component_of_wind_isobaric" });
			GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), globalOptions
				, -30000, -1);



			// 二维动态风场
			//globalOptions[VolumeOptions::Config::NameClipRange] = "70.0 0.0 140.0 60.0";
			//GribReader::extract(computeList, std::make_shared<NcAlgorithmUV>(), globalOptions
			//	, 0, -1);

			break;
		}
	}
	{
		//String gribPath = joinPath(dataPath, U2A("海南\\cloud3d"));
		//auto files = FileUtil::findFiles(gribPath);
		//for (const auto& f : files)
		//{
		//	if (f == "." || f == "..") continue;
		//	String gibName1 = joinPath(gribPath, f);
		//	VolumeComputeList computeList;
		//	//String cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\Hainan\\cloud3d");
		//	String cachePath = U2A("e:\\test");
		//	globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
		//	GribReader reader;
		//	if (!reader.open(gibName1, true)) continue;
		//	globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
		//	globalOptions[VolumeOptions::Config::NameEncodeRange] = VolumeEncoder::EncodeRangeToString(VolumeEncoder::EncodeRangePercent);
		//	globalOptions[VolumeOptions::Config::NameClipRange] = "106.0 14.0 130.0 40.0";
		//	globalOptions[VolumeOptions::Config::NameClipRange] = "103.0 12.0 119.0 25.0";
		//	reader.extract("Cloud_cover_isobaric", globalOptions, -1, -1);
		//}
	}
#endif 

#if 0
	cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\Hainan\\swan2");
	globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
	String gribPath = joinPath(dataPath, U2A("海南\\数据"));
	auto files = FileUtil::findFiles(gribPath);
	for (const auto& f : files)
	{
		if (f == "." || f == "..") continue;
		String fileName = U2A(joinPath(dataPath, "海南\\数据", f));
		CSwan reader;
		reader.extract(fileName, globalOptions);
	}
#endif

	// 涌浪
#if 0
	{
		String gibName1 = joinPath(dataPath, U2A("海南\\gefs.wave.t18z.c00.global.0p25.f063.grib2"));
		VolumeComputeList computeList;
		String cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\SampleData\\wave");
		globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
		globalOptions[VolumeOptions::Config::NameFillValue] = "9999.0";
		GribReader reader;
		reader.open(gibName1, true);
		globalOptions[VolumeOptions::Config::NameWriter] = VolumeOptions::Config::ValueD3Writer;
		computeList.push_back({ gibName1 ,"u-component_of_wind_surface" });
		computeList.push_back({ gibName1 ,"v-component_of_wind_surface" });
		GribReader::extract(computeList, std::make_shared<NcAlgorithmUV>(), globalOptions
			, 0, -1);
	}
#endif

#if 1
	cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\SampleData\\EC");
	globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
	dataPath = joinPath(dataPath, U2A("河南\\2024072212"));

	auto fileVec = FileUtil::findFiles(dataPath);
	for (auto file : fileVec)
	{
		if (!StringUtil::endsWith(file, ".grib", false)) continue;
		String gibName1 = joinPath(dataPath, file);
		GribReader reader;
		reader.open(gibName1, true);
		VolumeComputeList computeList;
		computeList.push_back({ gibName1 ,"U_component_of_wind_isobaric" });
		computeList.push_back({ gibName1 ,"V_component_of_wind_isobaric" });

		class MarchingCubesWriter : public OCPP::VolumeWriter
		{
		public:
			virtual bool write(const VolumeGridData& ncGridData, const VolumeOptions& ncOptions)
			{
				String fileName = generateOutputName(ncGridData, ncOptions);
				String path = getOutputPath();
				VolumeMesh volumeMesh;
				volumeMesh.convert(joinPath(path, fileName), { 15.0f,20.0f }, 7, ncGridData);
				return true;
			}
		};
		auto* myWriter = new MarchingCubesWriter();
		myWriter->setOutputPath(cachePath);
		VolumeOptions vOptions(globalOptions);
		vOptions.setWriter(myWriter);

		GribReader::extract(computeList, std::make_shared<NcAlgorithmVecLength>(), vOptions
			, -1, -1);
	}
#endif
#if 0
	{
		String name = "ept_2024090522.nc";

		cachePath = U2A("\\\\10.104.207.155\\Cesium\\Assets\\2024\\SampleData\\EC");
		globalOptions[VolumeOptions::Config::NameOutputPath] = cachePath;
		globalOptions[VolumeOptions::Config::NameClipRange] = "103.0 12.0 119.0 25.0";
		globalOptions[VolumeOptions::Config::NameClipRange] = "103.0 12.0 140.0 42.0";
		String gibName1 = joinPath(dataPath, U2A("垂直观测\\") + name);
		NetCDFReader reader;
		reader.open(gibName1, true);

		class MarchingCubesWriter : public OCPP::VolumeWriter
		{
		public:
			String name;
			MarchingCubesWriter(String _name) {
				name = _name;
			}
			virtual String generateOutputName(const VolumeGridData& ncGridData, const VolumeOptions& ncOptions)
			{
				return StringUtil::replaceAll(name, ".nc", "");
			}

			virtual bool write(const VolumeGridData& ncGridData, const VolumeOptions& ncOptions)
			{
				FloatVector isoValues = { 80.0f,90.0f,100.0f };
				String fileName = generateOutputName(ncGridData, ncOptions);
				String path = getOutputPath();
				VolumeMesh volumeMesh;
				volumeMesh.convert(joinPath(path, fileName), isoValues, 13, ncGridData);
				return true;
			}
		};
		auto* myWriter = new MarchingCubesWriter(name);
		myWriter->setOutputPath(cachePath);
		VolumeOptions vOptions(globalOptions);
		vOptions.setWriter(myWriter);

		vOptions.nameDimZ = { "isobaricInhPa" };

		reader.extract("ept", vOptions, -1, -1);
	}
#endif
}
